
package com.syz.fs.http;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Properties;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;


/**
 * 基于 http 协议的 文件服务器 ，，用于下载文件
 * http://127.0.0.1:8080/src/com/syz/netty
 * 
 * 使用方法，，基于mvn 构建，，直接 放在 指定路径，，执行bin方法，，即可。。
 * 
 * 注意 相对于 classpath 路径，也就是 bin 路径为 跟路径，，不能超越
 * @author SYZ
 * @date 2017年11月22日 下午5:33:16
 * @version 1.0.0
 * @see com.syz.netty.protocol.http.fileServer.HttpFileServer
 */
public class HttpFileServer {

	private static final String DEFAULT_URL = "/"; //当前路径，，，只要开启jar  那么当前路径的文件都是可以下载的。

	
	private static Properties prop ; 
	static{
		prop = new Properties();
		URL url = HttpFileServerHandler.class.getClassLoader().getResource("app.properties");
		try {
			prop.load(new FileInputStream(new File(url.toURI())));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
	}
	public void run(final int port, final String url) throws Exception {
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			ServerBootstrap b = new ServerBootstrap();
			b.group(bossGroup, workerGroup)
					.channel(NioServerSocketChannel.class)
					.childHandler(new ChannelInitializer<SocketChannel>() {
						@Override
						protected void initChannel(SocketChannel ch)
								throws Exception {
							ch.pipeline().addLast("http-decoder", new HttpRequestDecoder());//HTTP协议解码
							ch.pipeline().addLast("http-aggregator", new HttpObjectAggregator(65536));
							ch.pipeline().addLast("http-encoder", new HttpResponseEncoder());//HTTP协议编码
							ch.pipeline().addLast("http-chunked", new ChunkedWriteHandler());//文件流编码
							ch.pipeline().addLast("fileServerHandler", new HttpFileServerHandler(url)); //用户处理
						}
					});
			ChannelFuture future = b.bind("0.0.0.0",port).sync(); //不能写  127.0.0.1；这样只能本地访问。   可以为0.0.0.0 或者 ::0 （部分linux不支持该写法）或者不写。
			System.out.println("HTTP文件目录服务器启动，网址是 : " + "http://127.0.0.1:"
					+ port + url);
			future.channel().closeFuture().sync();
		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}

	public static void main(String[] args) throws Exception {
		int port = Integer.parseInt(prop.getProperty("server.port","8080"));
		
		String url = DEFAULT_URL;
		if (args.length > 1)
			url = args[1];
		new HttpFileServer().run(port, url);
	}
}
